﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using WMSTest.OnlineMapRequests;

namespace WMSTest.WebMapResource
{
    class OnlineMapResource
    {
        //256x256 is what is used for the ArcGIS JavaScript API, so I'll go with that
        private const int TILE_WIDTH = 256;
        private const int TILE_HEIGHT = 256;

        public MapRequest ExportMapRequester; //this should be abstracted for multiple online service types

        public OnlineMapResource(MapRequest ExportMapRequester)
        {
            this.ExportMapRequester = ExportMapRequester;
        }


        public List<ImageTile> GetTiles(Extent extent, MapSize mapSize)
        {
            List<ImageTile> imageTileList = new List<ImageTile>();

            //total number of tiles required
            int numTilesY = (int)Math.Ceiling((float)mapSize.Height / TILE_HEIGHT);
            int numTilesX = (int)Math.Ceiling((float)mapSize.Width / TILE_WIDTH);

            //number of full size tiles required
            int numFullTilesY = mapSize.Height / TILE_HEIGHT;
            int numFullTilesX = mapSize.Width / TILE_WIDTH;

            //calculate the coordinate increment in each direction
            double ylen = (extent.ymax - extent.ymin) / numTilesY;
            double xlen = (extent.xmax - extent.xmin) / numTilesX;

            for (int y = 0; y < numTilesY; y++)
            {
                int currHeight = TILE_HEIGHT;

                double currYmin = extent.ymin + y*ylen;
                double currYmax = currYmin + ylen;

                if (y == numFullTilesY) //if we have a partial tile in the y-direction
                {
                    currHeight = mapSize.Height % TILE_HEIGHT;
                    currYmax = extent.ymax;
                }

                for (int x = 0; x < numTilesX; x++)
                {
                    int currWidth = TILE_WIDTH;
                    
                    double currXmin = extent.xmin + x * xlen;
		            double currXmax = currXmin + xlen;

                    if (x == numFullTilesX) //if we have a partial tile in the x-direction
                    {
                        currWidth = mapSize.Width % TILE_WIDTH;
                        currXmax = extent.xmax;
                    }

                    Console.WriteLine("Fetching tile #" + y.ToString() + x.ToString());
                    
                    ExportMapRequester.SetBbox(currXmin, currYmin, currXmax, currYmax);
                    ExportMapRequester.SetSize(currWidth, currHeight);

                    HttpWebResponse response = ExportMapRequester.PerformExportMapRequest();
                   
                    StreamReader reader = new StreamReader(response.GetResponseStream());
                    BinaryReader binReader = new BinaryReader(response.GetResponseStream());
                    byte[] imageData = binReader.ReadBytes((int)response.ContentLength);

                    ImageTile newTile = 
                        new ImageTile(currWidth, currHeight, ExportMapRequester.ImageFormatString, imageData);

                    newTile.Name = "tile" + y.ToString() + x.ToString();

                    imageTileList.Add(newTile);
                }


            }

            return imageTileList;
        }

      

    }
}
